home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-11-27 | 60.5 KB | 1,452 lines | [TEXT/CWIE] |
-
- BSP TREE FREQUENTLY ASKED QUESTIONS (FAQ)
-
-
- _________________________________________________________________
-
- Questions
-
-
- 1. About this document
- 2. Acknowledgements
- 3. How can you contribute?
- 4. About the pseudo C++ code
- 5. What is a BSP Tree?
- 6. How do you build a BSP Tree?
- 7. How do you partition a polygon with a plane?
- 8. How do you remove hidden surfaces with a BSP Tree?
- 9. How do you compute analytic visibility with a BSP Tree?
- 10. How do you accelerate ray tracing with a BSP Tree?
- 11. How do you perform boolean operations on polytopes with a BSP
- Tree?
- 12. How do you perform collision detection with a BSP Tree?
- 13. How do you handle dynamic scenes with a BSP Tree?
- 14. How do you compute shadows with a BSP Tree?
- 15. How do you extract connectivity information from BSP Trees?
- 16. How are BSP Trees useful for robot motion planning?
- 17. How are BSP Trees used in DOOM?
- 18. How can you make a BSP Tree more robust?
- 19. How efficient is a BSP Tree?
- 20. How can you make a BSP Tree more efficient?
- 21. How can you avoid recursion?
- 22. What is the history of BSP Trees?
- 23. Where can you find sample code and related online resources?
- 24. References
-
-
- _________________________________________________________________
-
- Answers
-
- _
- About this document_
-
- _General_
- The purpose of this document is to provide answers to Frequently
- Asked Questions about Binary Space Partitioning (BSP) Trees. This
- document will be posted monthly to comp.graphics.algorithms. It is
- also available via WWW at the URL:
-
- http://www.qualia.com/bspfaq/
-
-
- The most recent newsgroup posting of this document is available
- via ftp at the following URLs:
-
- file://www.qualia.com/pub/bspfaq/bspfaq.txt
- ftp://rtfm.mit.edu/pub/usenet/news.answers/graphics/bsptree-
- faq
-
-
- _Requesting the FAQ by mail_
- You can request that the FAQ be mailed to you in plain text and
- HTML formats by sending e-mail to bspfaq@qualia.com with a subject
- line of "SEND BSP TREE [what]". The "[what]" should be replaced
- with any combination of "TEXT" and "HTML". Respectively, these
- will return to you a plain text version of the FAQ, and an HTML
- formatted version of the FAQ viewable with Mosaic or Netscape.
-
- _Copyrights and distribution_
- This document is maintained by Bretton Wade, lead developer for
- Qualia, Incorporated, and a graduate of the Cornell University
- Program of Computer Graphics.
-
- This document, and all its associated parts, are Copyright ©
- 1995, Bretton Wade. All rights reserved. Permisson to distribute
- this collection, in part or full, via electronic means (emailed,
- posted or archived) or printed copy are granted providing that no
- charges are involved, reasonable attempt is made to use the most
- current version, and all credits and copyright notices are
- retained. If you make a link to the WWW page, please inform the
- maintainer so he can construct reciprocal links.
-
- Requests for other distribution rights, including incorporation in
- commercial products, such as books, magazine articles, CD-ROMs,
- and binary applications should be made to bspfaq@qualia.com.
-
- _Warranty and disclaimer_
- This article is provided as is without any express or implied
- warranties. While every effort has been taken to ensure the
- accuracy of the information contained in this article, the
- author/maintainer/contributors assume(s) no responsibility for
- errors or omissions, or for damages resulting from the use of the
- information contained herein.
-
- The contents of this article do not necessarily represent the
- opinions of Qualia, Incorporated.
- --
- _Last Update: 11/27/95 16:26:21_
-
- _
- Acknowledgements_
-
- _About the contributors_
- This document would not have been possible without the selfless
- contributions and efforts of many individuals. I would like to
- take the opportunity to thank each one of them. Please be aware
- that these people may not be amenable to recieving e-mail on a
- random basis. If you have any special questions, please contact
- Bretton Wade (bwade@qualia.com or bspfaq@qualia.com) before
- trying to contact anyone else on this list.
-
- _Contributors_
- + Bruce Naylor (naylor@research.att.com)
- + Richard Lobb (richard@cs.auckland.ac.nz)
- + Dani Lischinski (danix@cs.washington.edu)
- + Chris Schoeneman (crs@lightscape.com)
- + Philip Hubbard (pmh@graphics.cornell.edu)
- + Jim Arvo (arvo@graphics.cornell.edu)
- + Kevin Ryan (kryan@access.digex.net)
- + Joseph Fiore (fiore@cs.buffalo.edu)
- + Lukas Rosenthaler (rosenth@foto.chemie.unibas.ch)
- + Anson Tsao (ansont@hookup.net)
- + Robert Zawarski (zawarski@chaph.usc.edu)
- + Ron Capelli (capelli@vnet.ibm.com)
- + Eric A. Haines (erich@eye.com)
- + Ian CR Mapleson (mapleson@cee.hw.ac.uk)
- + Richard Dorman (richard@cs.wits.ac.za)
- + Steve Larsen (larsen@sunset.cs.utah.edu)
- + Timothy Miller (tsm@cs.brown.edu)
- + Ben Trumbore (wbt@graphics.cornell.edu)
- + Richard Matthias (richardm@cogs.susx.ac.uk)
- + Ken Shoemake (shoemake@graphics.cis.upenn.edu)
- + Seth Teller (seth@theory.lcs.mit.edu)
- + Peter Shirley (shirley@graphics.cornell.edu)
- + Michael Abrash (mikeab@idece2.idsoftware.com)
- + Robert Schmidt (robert@idt.unit.no)
- + Samuel P. Uselton (uselton@nas.nasa.gov)
-
-
- If I have neglected to mention your name, and you contributed,
- please let me know immediately!
- --
- _Last Update: 11/27/95 16:26:21_
-
- _
- How can you contribute?_
-
- Please send all new questions, corrections, suggestions, and
- contributions to bsp-faq@graphics.cornell.edu.
- --
- _Last Update: 11/27/95 16:26:21_
-
- _
- About the pseudo C++ code_
-
- _Overview_
- The general efficiency of C++ makes it a well suited language for
- programming computer graphics. Furthermore, the abstract nature of
- the language allows it to be used effectively as a psuedo code for
- demonstrative purposes. I will use C++ notation for all the
- examples in this document.
-
- In order to provide effective examples, it is necessary to assume
- that certain classes already exist, and can be used without
- presenting excessive details of their operation. Basic classes
- such as lists and arrays fall into this category.
-
- Other classes which will be very useful for examples need to be
- presented here, but the definitions will be generic to allow for
- freedom of interpretation. I assume points and vectors to each be
- an array of 3 real numbers (X, Y, Z).
-
- Planes are represented as an array of 4 real numbers (A, B, C, D).
- The vector (A, B, C) is the normal vector to the plane. Polygons
- are structures composited from an array of points, which are the
- vertices, and a plane.
-
- The overloaded operator for a dot product (inner product, scalar
- product, etc.) of two vectors is the '|' symbol. This has two
- advantages, the first of which is that it can't be confused with
- the scalar multiplication operator. The second is that precedence
- of C++ operators will usually require that dot product operations
- be parenthesized, which is consistent with the linear algebra
- notation for an inner product.
-
- The code for BSP trees presented here is intended to be
- educational, and may or may not be very efficient. For the sake of
- clarity, the BSP tree itself will not be defined as a class.
- --
- _Last Update: 11/27/95 16:26:21_
-
- _
- What is a BSP Tree?_
-
- _Overview_ A Binary Space Partitioning (BSP) tree represents a
- recursive, hierarchical partitioning, or subdivision, of
- n-dimensional space into convex subspaces. BSP tree construction
- is a process which takes a subspace and partitions it by any
- hyperplane that intersects the interior of that subspace. The
- result is two new subspaces that can be further partitioned by
- recursive application of the method.
-
- A "hyperplane" in n-dimensional space is an n-1 dimensional object
- which can be used to divide the space into two half-spaces. For
- example, in three dimensional space, the "hyperplane" is a plane.
- In two dimensional space, a line is used.
-
- BSP trees are extremely versatile, because they are powerful
- sorting and classification structures. They have uses ranging from
- hidden surface removal and ray tracing hierarchies to solid
- modeling and robot motion planning.
-
- _Example_
- An easy way to think about BSP trees is to limit the discussion to
- two dimensions. To simplify the situation, let's say that we will
- use only lines parallel to the X or Y axis, and that we will
- divide the space equally at each node. For example, given a square
- somewhere in the XY plane, we select the first split, and thus the
- root of the BSP Tree, to cut the square in half in the X
- direction. At each slice, we will choose a line of the opposite
- orientation from the last one, so the second slice will divide
- each of the new pieces in the Y direction. This process will
- continue recursively until we reach a stopping point, and looks
- like this:
-
- +-----------+ +-----+-----+ +-----+-----+
- | | | | | | | |
- | | | | | | d | |
- | | | | | | | |
- | a | -> | b X c | -> +--Y--+ f | -> ...
- | | | | | | | |
- | | | | | | e | |
- | | | | | | | |
- +-----------+ +-----+-----+ +-----+-----+
-
-
- The resulting BSP tree looks like this at each step:
- _a_ _X_ _X_ ...
- _ _ -/ \+ _ _ -/ \+
- _ _ / \ _ _ / \
- _b_ _c_ _Y_ _f_
- _ _ -/ \+
- _ _ / \
- _e_ _d_
-
-
- _Other space partitioning structures_
- BSP trees are closely related to Quadtrees and Octrees. Quadtrees
- and Octrees are space partitioning trees which recursively divide
- subspaces into four and eight new subspaces, respectively. A BSP
- Tree can be used to simulate both of these structures.
- --
- _Last Update: 11/27/95 16:26:21_
-
- _
- How do you build a BSP Tree?_
-
- _Overview_
- Given a set of polygons in three dimensional space, we want to
- build a BSP tree which contains all of the polygons. For now, we
- will ignore the question of how the resulting tree is going to be
- used.
-
- The algorithm to build a BSP tree is very simple:
-
- 1. Select a partition plane.
- 2. Partition the set of polygons with the plane.
- 3. Recurse with each of the two new sets.
-
-
- _Choosing the partition plane_
- The choice of partition plane depends on how the tree will be
- used, and what sort of efficiency criteria you have for the
- construction. For some purposes, it is appropriate to choose the
- partition plane from the input set of polygons. Other applications
- may benefit more from axis aligned orthogonal partitions.
-
- In any case, you want to evaluate how your choice will affect the
- results. It is desirable to have a balanced tree, where each leaf
- contains roughly the same number of polygons. However, there is
- some cost in achieving this. If a polygon happens to span the
- partition plane, it will be split into two or more pieces. A poor
- choice of the partition plane can result in many such splits, and
- a marked increase in the number of polygons. Usually there will be
- some trade off between a well balanced tree and a large number of
- splits.
-
- _Partitioning polygons_
- Partitioning a set of polygons with a plane is done by classifying
- each member of the set with respect to the plane. If a polygon
- lies entirely to one side or the other of the plane, then it is
- not modified, and is added to the partition set for the side that
- it is on. If a polygon spans the plane, it is split into two or
- more pieces and the resulting parts are added to the sets
- associated with either side as appropriate.
-
- _When to stop_
- The decision to terminate tree construction is, again, a matter of
- the specific application. Some methods terminate when the number
- of polygons in a leaf node is below a maximum value. Other methods
- continue until every polygon is placed in an internal node.
- Another criteria is a maximum tree depth.
-
- _Pseudo C++ code example_
- Here is an example of how you might code a BSP tree:
-
- struct BSP_tree
- {
- plane partition;
- list polygons;
- BSP_tree *front,
- *back;
- };
- This structure definition will be used for all subsequent example
- code. It stores pointers to its children, the partitioning plane
- for the node, and a list of polygons coincident with the partition
- plane. For this example, there will always be at least one polygon
- in the coincident list: the polygon used to determine the
- partition plane. A constructor method for this structure should
- initialize the child pointers to NULL.
-
- void Build_BSP_Tree (BSP_tree *tree, list polygons)
- {
- polygon *root = polygons.Get_From_List ();
- tree->partition = root->Get_Plane ();
- tree->polygons.Add_To_List (root);
- list front_list,
- back_list;
- polygon *poly;
- while ((poly = polygons.Get_From_List ()) != 0)
- {
- int result = tree->partition.Classify_Polygon (poly);
- switch (result)
- {
- case COINCIDENT:
- tree->polygons.Add_To_List (poly);
- break;
- case IN_BACK_OF:
- backlist.Add_To_List (poly);
- break;
- case IN_FRONT_OF:
- frontlist.Add_To_List (poly);
- break;
- case SPANNING:
- polygon *front_piece, *back_piece;
- Split_Polygon (poly, tree->partition, front_piece, back_piece);
- backlist.Add_To_List (back_piece);
- frontlist.Add_To_List (front_piece);
- break;
- }
- }
- if ( ! front_list.Is_Empty_List ())
- {
- tree->front = new BSP_tree;
- Build_BSP_Tree (tree->front, front_list);
- }
- if ( ! back_list.Is_Empty_List ())
- {
- tree->back = new BSP_tree;
- Build_BSP_Tree (tree->back, back_list);
- }
- }
- This routine recursively constructs a BSP tree using the above
- definition. It takes the first polygon from the input list and
- uses it to partition the remainder of the set. The routine then
- calls itself recursively with each of the two partitions. This
- implementation assumes that all of the input polygons are convex.
-
- One obvious improvement to this example is to choose the
- partitioning plane more intelligently. This issue is addressed
- separately in the section, "How can you make a BSP Tree more
- efficient?".
- --
- _Last Update: 11/27/95 16:26:21_
-
- _
- How do you partition a polygon with a plane?_
-
- _Overview_
- Partitioning a polygon with a plane is a matter of determining
- which side of the plane the polygon is on. This is referred to as
- a front/back test, and is performed by testing each point in the
- polygon against the plane. If all of the points lie to one side of
- the plane, then the entire polygon is on that side and does not
- need to be split. If some points lie on both sides of the plane,
- then the polygon is split into two or more pieces.
-
- The basic algorithm is to loop across all the edges of the polygon
- and find those for which one vertex is on each side of the
- partition plane. The intersection points of these edges and the
- plane are computed, and those points are used as new vertices for
- the resulting pieces.
-
- _Implementation notes_
- Classifying a point with respect to a plane is done by passing the
- (x, y, z) values of the point into the plane equation, Ax + By +
- Cz + D = 0. The result of this operation is the distance from the
- plane to the point along the plane's normal vector. It will be
- positive if the point is on the side of the plane pointed to by
- the normal vector, negative otherwise. If the result is 0, the
- point is on the plane.
-
- For those not familiar with the plane equation, The values A, B,
- and C are the coordinate values of the normal vector. D can be
- calculated by substituting a point known to be on the plane for x,
- y, and z.
-
- Convex polygons are generally easier to deal with in BSP tree
- construction than concave ones, because splitting them with a
- plane always results in exactly two convex pieces. Furthermore,
- the algorithm for splitting convex polygons is straightforward and
- robust. Splitting of concave polygons, especially self
- intersecting ones, is a significant problem in its own right.
-
- _Pseudo C++ code example_
- Here is a very basic function to split a convex polygon with a
- plane:
-
- void Split_Polygon (polygon *poly, plane *part, polygon *&front, polygon *&back
- )
- {
- int count = poly->NumVertices (),
- out_c = 0, in_c = 0;
- point ptA, ptB,
- outpts[MAXPTS],
- inpts[MAXPTS];
- real sideA, sideB;
- ptA = poly->Vertex (count - 1);
- sideA = part->Classify_Point (ptA);
- for (short i = -1; ++i < count;)
- {
- ptB = poly->Vertex (i);
- sideB = part->Classify_Point (ptB);
- if (sideB > 0)
- {
- if (sideA < 0)
- {
- // compute the intersection point of the line
- // from point A to point B with the partition
- // plane. This is a simple ray-plane intersection.
- vector v = ptB - ptA;
- real sect = - part->Classify_Point (ptA) / (part->Normal () | v);
- outpts[out_c++] = inpts[in_c++] = ptA + (v * sect);
- }
- outpts[out_c++] = ptB;
- }
- else if (sideB < 0)
- {
- if (sideA > 0)
- {
- // compute the intersection point of the line
- // from point A to point B with the partition
- // plane. This is a simple ray-plane intersection.
- vector v = ptB - ptA;
- real sect = - part->Classify_Point (ptA) / (part->Normal () | v);
- outpts[out_c++] = inpts[in_c++] = ptA + (v * sect);
- }
- inpts[in_c++] = ptB;
- }
- else
- outpts[out_c++] = inpts[in_c++] = ptB;
- ptA = ptB;
- sideA = sideB;
- }
- front = new polygon (outpts, out_c);
- back = new polygon (inpts, in_c);
- }
- A simple extension to this code that is good for BSP trees is to
- combine its functionality with the routine to classify a polygon
- with respect to a plane.
-
- Note that this code is not robust, since numerical stability may
- cause errors in the classification of a point. The standard
- solution is to make the plane "thick" by use of an _epsilon_
- value.
- --
- _Last Update: 11/27/95 16:26:21_
-
- _
- How do you remove hidden surfaces with a BSP Tree?_
-
- _Overview_
- Probably the most common application of BSP trees is hidden
- surface removal in three dimensions. BSP trees provide an elegant,
- efficient method for sorting polygons via a depth first tree walk.
- This fact can be exploited in a back to front "painter's
- algorithm" approach to the visible surface problem, or a front to
- back scanline approach.
-
- BSP trees are well suited to interactive display of static (not
- moving) geometry because the tree can be constructed as a
- preprocess. Then the display from any arbitrary viewpoint can be
- done in linear time. Adding dynamic (moving) objects to the scene
- is discussed in another section of this document.
-
- _Painter's algorithm_
- The idea behind the painter's algorithm is to draw polygons far
- away from the eye first, followed by drawing those that are close
- to the eye. Hidden surfaces will be written over in the image as
- the surfaces that obscure them are drawn. One condition for a
- successful painter's algorithm is that there be a single plane
- which separates any two objects. This means that it might be
- necessary to split polygons in certain configurations. For
- example, this case can not be drawn correctly with a painter's
- algorithm:
-
- +------+
- | |
- +---------------| |--+
- | | | |
- | | | |
- | | | |
- | +--------| |--+
- | | | |
- +--| |--------+ |
- | | | |
- | | | |
- | | | |
- +--| |---------------+
- | |
- +------+
- One reason that BSP trees are so elegant for the painter's algorithm
- is that the splitting of difficult polygons is an automatic part
- of tree construction. Note that only one of these two polygons
- needs to be split in order to resolve the problem.
-
- To draw the contents of the tree, perform a back to front tree
- traversal. Begin at the root node and classify the eye point with
- respect to its partition plane. Draw the subtree at the far child
- from the eye, then draw the polygons in this node, then draw the
- near subtree. Repeat this procedure recursively for each subtree.
-
- _Scanline hidden surface removal_
- It is just as easy to traverse the BSP tree in front to back order
- as it is for back to front. We can use this to our advantage in a
- scanline method method by using a write mask which will prevent
- pixels from being written more than once. This will represent
- significant speedups if a complex lighting model is evaluated for
- each pixel, because the painter's algorithm will blindly evaluate
- the same pixel many times.
-
- The trick to making a scanline approach successful is to have an
- efficient method for masking pixels. One way to do this is to
- maintain a list of pixel spans which have not yet been written to
- for each scan line. For each polygon scan converted, only pixels
- in the available spans are written, and the spans are updated
- accordingly.
-
- The scan line spans can be represented as binary trees, which are
- just one dimensional BSP trees. This technique can be expanded to
- a two dimensional screen coverage algorithm using a two
- dimensional BSP tree to represent the masked regions. Any convex
- partitioning scheme, such as a quadtree, can be used with similar
- effect.
-
- _Implementation notes_
- When building a BSP tree specifically for hidden surface removal,
- the partition planes are usually chosen from the input polygon
- set. However, any arbitrary plane can be used if there are no
- intersecting or concave polygons, as in the example above.
-
- _Pseudo C++ code example_
- Using the BSP_tree structure defined in the section, "How do you
- build a BSP Tree?", here is a simple example of a back to front
- tree traversal:
-
- void Draw_BSP_Tree (BSP_tree *tree, point eye)
- {
- real result = tree->partition.Classify_Point (eye);
- if (result > 0)
- {
- Draw_BSP_Tree (tree->back, eye);
- tree->polygons.Draw_Polygon_List ();
- Draw_BSP_Tree (tree->front, eye);
- }
- else if (result < 0)
- {
- Draw_BSP_Tree (tree->front, eye);
- tree->polygons.Draw_Polygon_List ();
- Draw_BSP_Tree (tree->back, eye);
- }
- else // result is 0
- {
- // the eye point is on the partition plane...
- Draw_BSP_Tree (tree->front, eye);
- Draw_BSP_Tree (tree->back, eye);
- }
- }
- If the eye point is classified as being on the partition plane, the
- drawing order is unclear. This is not a problem if the
- Draw_Polygon_List routine is smart enough to not draw polygons
- that are not within the viewing frustum. The coincident polygon
- list does not need to be drawn in this case, because those
- polygons will not be visible to the user.
-
- It is possible to substantially improve the quality of this
- example by including the viewing direction vector in the
- computation. You can determine that entire subtrees are behind the
- viewer by comparing the view vector to the partition plane normal
- vector. This test can also make a better decision about tree
- drawing when the eye point lies on the partition plane. It is
- worth noting that this improvement resembles the method for
- tracing a ray through a BSP tree, which is discussed in another
- section of this document.
-
- Front to back tree traversal is accomplished in exactly the same
- manner, except that the recursive calls to Draw_BSP_Tree occur in
- reverse order.
- --
- _Last Update: 11/27/95 16:26:21_
-
- _
- How do you compute analytic visibility with a BSP Tree?_
-
- _Overview_
-
- --
- _Last Update: 11/27/95 16:26:21_
-
- _
- How do you accelerate ray tracing with a BSP Tree?_
-
- _Overview_
- Ray tracing a BSP tree is very similar to hidden surface removal
- with a BSP tree. The algorithm is a simple forward tree walk, with
- a few additions that apply to ray casting.
-
- MORE TO COME
-
-
- --
- _Last Update: 11/27/95 16:26:21_
-
- _
- How do you perform boolean operations on polytopes with a BSP Tree?_
-
- _Overview_
- There are two major classes of solid modeling methods with BSP
- trees. For both methods, it is useful to introduce the notion of
- an in/out test.
-
- An in/out test is a different way of talking about the front/back
- test we have been using to classify points with respect to planes.
- The necessity for this shift in thought is evident when
- considering polytopes instead of just polygons. A point can not be
- merely in front or back of a polytope, but inside or outside.
- Somewhat formally, a point is inside of a polytope if it is inside
- of, or in back of, each hyperplane which composes the polytope,
- otherwise it is outside.
-
- _Incremental construction_
- Incremental construction of a BSP Tree is the process of inserting
- convex polytopes into the tree one by one. Each polytope has to be
- processed according to the operation desired.
-
- It is useful to examine the construction process in two
- dimensions. Consider the following figure:
-
-
- A B
- +-------------+
- | |
- | |
- | E | F
- | +-----+-------+
- | | | |
- | | | |
- | | | |
- +-------+-----+ |
- D | C |
- | |
- | |
- +-------------+
- H G
- Two polygons, ABCD, and EFGH, are to be inserted into the tree. We
- wish to find the union of these two polygons. Start by inserting
- polygon ABCD into the tree, choosing the splitting hyperplanes to
- be coincident with the edges. The tree looks like this after
- insertion of ABCD:
-
-
- _AB_
- -/ \+
- / \
- / *
- _BC_
- -/ \+
- / \
- / *
- _CD_
- -/ \+
- / \
- / *
- _DA_
- -/ \+
- / \
- * *
- Now, polygon EFGH is inserted into the tree, one polygon at a time.
- The result looks like this:
-
- A B
- +-------------+
- | |
- | |
- | E |J F
- | +-----+-------+
- | | | |
- | | | |
- | | | |
- +-------+-----+ |
- D |L :C |
- | : |
- | : |
- +-----+-------+
- H K G
-
- AB
- -/ \+
- / \
- / *
- BC
- -/ \+
- / \
- / \
- CD \
- -/ \+ \
- / \ \
- / \ \
- DA \ \
- -/ \+ \ \
- / \ \ \
- / * \ \
- EJ KH \
- -/ \+ -/ \+ \
- / \ / \ \
- / * / * \
- LE HL JF
- -/ \+ -/ \+ -/ \+
- / \ / \ / \
- * * * * FG *
- -/ \+
- / \
- / *
- GK
- -/ \+
- / \
- * *
- Notice that when we insert EFGH, we split edges EF and HE along the
- edges of ABCD. this has the effect of dividing these segments into
- pieces which are inside ABCD, and outside ABCD. Segments EJ and LE
- will not be part of the boundary of the union. We could have saved
- our selves some work by not inserting them into the tree at all.
- For a union operation, you can always throw away segments that
- land in inside nodes. You must be careful about this though. What
- I mean is that any segments which land in inside nodes of side the
- pre-existing tree, not the tree as it is being constructed. EJ and
- LE landed in an inside node of the tree for polygon ABCD, and so
- can be discarded.
-
- Our tree now looks like this:
- A B
- +-------------+
- | |
- | |
- | |J F
- | +-------+
- | | |
- | | |
- | | |
- +-------+-----+ |
- D |L :C |
- | : |
- | : |
- +-----+-------+
- H K G
-
- AB
- -/ \+
- / \
- / *
- BC
- -/ \+
- / \
- / \
- CD \
- -/ \+ \
- / \ \
- / \ \
- DA \ \
- -/ \+ \ \
- / \ \ \
- * * \ \
- KH \
- -/ \+ \
- / \ \
- / * \
- HL JF
- -/ \+ -/ \+
- / \ / \
- * * FG *
- -/ \+
- / \
- / *
- GK
- -/ \+
- / \
- * *
- Now, we would like some way to eliminate the segments JC and CL, so
- that we will be left with the boundary segments of the union.
- Examine the segment BC in the tree. What we would like to do is
- split BC with the hyperplane JF. Conveniently, we can do this by
- _pushing_ the BC segment through the node for JF. The resulting
- segments can be classified with the rest of the JF subtree. Notice
- that the segment BJ lands in an out node, and that JC lands in an
- in node. Remembering that we can discard interior nodes, we can
- eliminate JC. The segment BJ replaces BC in the original tree.
- This process is repeated for segment CD, yielding the segments CL
- and LD. CL is discarded as landing in an interior node, and LD
- replaces CD in the original tree. The result looks like this:
- A B
- +-------------+
- | |
- | |
- | |J F
- | +-------+
- | |
- | |
- | L |
- +-------+ |
- D | |
- | |
- | |
- +-----+-------+
- H K G
-
- AB
- -/ \+
- / \
- / *
- BJ
- -/ \+
- / \
- / \
- LD \
- -/ \+ \
- / \ \
- / \ \
- DA \ \
- -/ \+ \ \
- / \ \ \
- * * \ \
- KH \
- -/ \+ \
- / \ \
- / * \
- HL JF
- -/ \+ -/ \+
- / \ / \
- * * FG *
- -/ \+
- / \
- / *
- GK
- -/ \+
- / \
- * *
- As you can see, the result is the union of the polygons ABCD and EFGH.
-
- To perform other boolean operations, the process is similar. For
- intersection, you discard segments which land in exterior nodes
- instead of internal ones. The difference operation is special. It
- requires that you invert the polytope before insertion. For simple
- objects, this can be achieved by scaling with a factor of -1. The
- insertion process is then cinducted as an intersection operation,
- where segments landing in external nodes are discarded.
-
- _Tree merging_
-
- --
- _Last Update: 11/27/95 16:26:21_
-
- _
- How do you perform collision detection with a BSP Tree?_
-
- _Overview_
- Detecting whether or not a point moving along a line intersects
- some object in space is essentially a ray tracing problem.
- Detecting whether or not two complex objects intersect is
- something of a tree merging problem.
-
- Typically, motion is computed in a series of _Euler_ steps. This
- just means that the motion is computed at discrete time intervals
- using some description of the speed of motion. For any given point
- P moving from point A with a velocity V, it's location can be
- computed at time T as P = A + (T * V).
-
- Consider the case where T = 1, and we are computing the motion in
- one second steps. To find out if the point P has collided with any
- part of the scene, we will first compute the endpoints of the
- motion for this time step. P1 = A + V, and P2 = A + (2 * V). These
- two endpoints will be classified with respect to the BSP tree. If
- P1 is outside of all objects, and P2 is inside some object, then
- an intersection has clearly occurred. However, if P2 is also
- outside, we still have to check for a collision in between.
-
- Two approaches are possible. The first is commonly used in
- applications like games, where speed is critical, and accuracy is
- not. This approach is to recursively divide the motion segment in
- half, and check the midpoint for containment by some object.
- Typically, it is good enough to say that an intersection occurred,
- and not be very accurate about where it occurred.
-
- The second approach, which is more accurate, but also more time
- consuming, is to treat the motion segment as a ray, and intersect
- the ray with the BSP Tree. This also has the advantage that the
- motion resulting from the impact can be computed more accurately.
- --
- _Last Update: 11/27/95 16:26:21_
-
- _
- How do you handle dynamic scenes with a BSP Tree?_
-
- _Overview_
- So far the discussion of BSP tree structures has been limited to
- handling objects that don't move. However, because the hidden
- surface removal algorithm is so simple and efficient, it would be
- nice if it could be used with dynamic scenes too. Faster animation
- is the goal for many applications, most especially games.
-
- The BSP tree hidden surface removal algorithm can easily be
- extended to allow for dynamic objects. For each frame, start with
- a BSP tree containing all the static objects in the scene, and
- reinsert the dynamic objects. While this is straightforward to
- implement, it can involve substantial computation.
-
- If a dynamic object is separated from each static object by a
- plane, the dynamic object can be represented as a single point
- regardless of its complexity. This can dramatically reduce the
- computation per frame because only one node per dynamic object is
- inserted into the BSP tree. Compare that to one node for every
- polygon in the object, and the reason for the savings is obvious.
- During tree traversal, each point is expanded into the original
- object.
-
- _Implementation notes_
- Inserting a point into the BSP tree is very cheap, because there
- is only one front/back test at each node. Points are never split,
- which explains the requirement of separation by a plane. The
- dynamic object will always be drawn completely in front of the
- static objects behind it.
-
- A dynamic object inserted into the tree as a point can become a
- child of either a static or dynamic node. If the parent is a
- static node, perform a front/back test and insert the new node
- appropriately. If it is a dynamic node, a different front/back
- test is necessary, because a point doesn't partition three
- dimesnional space. The correct front/back test is to simply
- compare distances to the eye. Once computed, this distance can be
- cached at the node until the frame is drawn.
-
- An alternative when inserting a dynamic node is to construct a
- plane whose normal is the vector from the point to the eye. This
- plane is used in front/back tests just like the partition plane in
- a static node. The plane should be computed lazily and it is not
- necessary to normalize the vector.
-
- Cleanup at the end of each frame is easy. A static node can never
- be a child of a dynamic node, since all dynamic nodes are inserted
- after the static tree is completed. This implies that all subtrees
- of dynamic nodes can be removed at the same time as the dynamic
- parent node.
-
- _Advanced methods_
- Tree merging, "ghosts", real dynamic trees... MORE TO COME
- --
- _Last Update: 11/27/95 16:26:21_
-
- _
- How do you compute shadows with a BSP Tree?_
-
- _Overview_
-
- --
- _Last Update: 11/27/95 16:26:21_
-
- _
- How do you extract connectivity information from BSP Trees?_
-
- _Overview_
-
- --
- _Last Update: 11/27/95 16:26:21_
-
- _
- How are BSP Trees useful for robot motion planning?_
-
- _Overview_
-
- --
- _Last Update: 11/27/95 16:26:21_
-
- _
- How are BSP Trees used in DOOM?_
-
- _Overview_
- Before you can understand how DOOM uses a BSP tree to accelerate
- its rendering process, you have to understand how the world is
- represented in DOOM. When someone creates a DOOM level in a level
- editor they draw linedefs in a 2d space. Yes, that's right, DOOM
- is only 2d. These linedefs (ignoring the special effects linedefs)
- must be arranged so that they form closed polygons. One linedef
- may be used to form the outline of two polygons (in which case it
- is known as a two-sided linedef) and one polygon may be contained
- within another, but no linedefs may cross. Each enclosed area of
- the world (i.e. polygon) is assigned a floor height, ceiling
- height, floor and ceiling textures, a lower texture and an upper
- texture. The lower texture is visible when a linedef is viewed
- from a direction where the floor is lower in the adjoining area.
- An equivalent thing is true for the upper texture. A set of these
- enclosed areas that all have the same attributes is known as a
- sector.
-
- When the level is saved by the editor some new information is
- created including the BSP tree for that level. Before the BSP tree
- can be created, all the sectors have to be split into convex
- polygons known as sub-sectors. If you had a sector that was a
- square area, then that would translate exactly into a sub-sector.
- Whereas if that sector was contained inside another larger square
- sector, the larger one would have to be split into four, four
- sided sub-sectors to make all the sub-sectors convex. When more
- complex sectors are split into sub-sectors the linedefs that bound
- that sector may need to be broken into smaller lengths. These
- linedef sections are called segs.
-
- Given a point on the 2d map, the renderer (which isn't discussed
- here) wants a list of all the segs that are visible from that
- viewpoint in closest first order. Because of the restrictions
- placed on the DOOM world, the renderer can easily tell when the
- screen has been filled so it can stop looking for segs at this
- time. This is quicker than rendering all the segs from back to
- front and using a method like painters algorithm.
-
- Each node in the BSP tree defines a partition line (this does not
- have be a linedef in the world but usually is) which is the
- equivalent to the partition plane of a 3d BSP tree. It then has
- left and right pointers which are either another node for further
- sub-division or a leaf, the leaf being a sub-sector in DOOM. The
- BSP tree in DOOM is effectively being used to sort whole
- sub-sectors rather than individual lines front to back. Each node
- also defines an orthogonal bounding box for each side of the
- partition. All segs on a particular side of the partition must be
- within that box. This speeds up the searching process by allowing
- whole branches of the tree to be discarded if that bounding box
- isn't visible. The test for visibility is simply if the bounding
- box lies wholly or partly within the cone defined by the left and
- right edges of the screen.
-
- During the display update process the BSP tree is searched
- starting from the node containing the sub-sector that the player
- is currently in. The search moves outwards through the tree
- (searching the other half of the current node before moving onto
- the other half of the parents node). When a partition test is
- performed the branch chosen is the one on the same side as the
- player. This facilitates the front to back searching. Each time a
- leaf is encountered the segs in that sub-sector are passed to the
- renderer. If the renderer has returned that the screen is filled
- then the process stops, otherwise it continues until the tree has
- been fully searched (in which case there is an error in the level
- design).
-
- In case you're thinking that it is inefficient to dump a whole
- sub-sectors worth of segs into the renderer at once, the segs in a
- sub-sector can be back-face culled very quickly. DOOM stores the
- angle of linedefs (of which segs are part). When the angle of the
- players view is calculated this allows segs to be culled in a
- single instruction! Angles are stored as a 16 bit number where 0
- is east an 65535 is 1/63336 south of east.
- --
- _Last Update: 11/27/95 16:26:21_
-
- _
- How can you make a BSP Tree more robust?_
-
- _Overview_
-
- --
- _Last Update: 11/27/95 16:26:21_
-
- _
- How efficient is a BSP Tree?_
-
- _Space complexity_
- For hidden surface removal and ray tracing accelleration, the
- upper bound is O(n ^ 2) for n polygons. The expected case is O(n)
- for most models. MORE LATER
-
- _Time complexity_
- For hidden surface removal and ray tracing accelleration, the
- upper bound is O(n ^ 2) for n polygons. The expected case is O(n)
- for most models. MORE LATER
- --
- _Last Update: 11/27/95 16:26:21_
-
- _
- How can you make a BSP Tree more efficient?_
-
- _Bounding volumes_
- Bounding spheres are simple to implement, take only a single plane
- comparison, using the center of the sphere.
-
- _Optimal trees_
- Construction of an optimal tree is an NP-complete problem. The
- problem is one of splitting versus tree balancing. These are
- mutually exclusive requirements. You should choose your strategy
- for building a good tree based on how you intend to use the tree.
-
- _Minimizing splitting_
- An obvious problem with BSP trees is that polygons get split
- during the construction phase, which results in a larger number of
- polygons. Larger numbers of polygons translate into larger storage
- requirements and longer tree traversal times. This is undesirable
- in all applications of BSP trees, so some scheme for minimizing
- splitting will improve tree performance.
-
- Bear in mind that minimization of splitting requires pre-existing
- knowledge about all of the polygons that will be inserted into the
- tree. This knowledge may not exist for interactive uses such as
- solid modelling.
-
- _Tree balancing_
- Tree balancing is important for uses which perform spatial
- classification of points, lines, and surfaces. This includes ray
- tracing and solid modelling. Tree balancing is important for these
- applications because the time complexity for classification is
- based on the depth of the tree. Unbalanced trees have deeper
- subtrees, and therefore have a worse worst case.
-
- For the hidden surface problem, balancing doesn't significantly
- affect runtime. This is because the expected time complexity for
- tree traversal is linear on the number of polygons in the tree,
- rather than the depth of the tree.
-
- _Balancing vs. splitting_
- If balancing is an important concern for your application, it will
- be necessary to trade off some balance for reduced splitting. If
- you are choosing your hyperplanes from the polygon candidates,
- then one way to optimize these two factors is to randomly select a
- small number of candidates. These new candidates are tested
- against the full list for splitting and balancing efficiency. A
- linear combination of the two efficiencies is used to rank the
- candidates, and the best one is chosen.
-
- _Reference Counting_
- _Other Optimizations_
-
- --
- _Last Update: 11/27/95 16:26:21_
-
- _
- How can you avoid recursion?_
-
- standard binary tree search/sort techniques apply.
- --
- _Last Update: 11/27/95 16:26:21_
-
- _
- What is the history of BSP Trees?_
-
- _Overview_
- Neophyte: How did the BSP-Tree come to be?
-
- Sage: Long ago in a small village in Nepal, a minor godling gave a
- special nut to the priests at an out of the way temple. With the
- nut, was a prophecy: When a group of three gurus, two with red
- hair, and the other who was not what he seemed, came to the temple
- on pilgrimage, if the nut was given unto them, and they nurtured
- it together, it would produce a tree of great benefit to mankind.
- Many years later, ...
-
- N: no! No! NO! The TRUE story.
-
- S: OK.
-
- Long ago (by computer industry standards) in a rapidly growing
- sunbelt city in Texas, a serendipitous convergence of unusual
- talents and personalities occurred. A brief burst of graphics
- wonderments appeared, and the convergence diverged under its own
- explosive production, leading to further graphics developments in
- several new locations. One of the wonderous paths followed ...
-
- N: ...No! The facts!
-
- S: Huh? Oh you want FACTS. Boring stuff?
-
- Henry Fuchs started teaching at an essentially brand new campus,
- the University of Texas at Dallas, in January 1975. He returned to
- Utah to complete his PhD the following summer. He returned to
- Dallas and taught for the 1975-76, 1976-77 and 1977-78 academic
- years, before being lured away to UNC-Chapel Hill.
-
- Zvi Kedem joined this faculty in the fall of 1975. He was (and
- still is I suppose) a "theory person," but a special theory
- person. He is good at applying theory to practical problems.
-
- Bruce Naylor had a bachelors degree from the U of Texas (Austin -
- "the real one"), in philosophy if I recall correctly. He had
- talked his way into a job at Texas Instruments in Dallas.
- (Something about philosophy makes you good in logic, which is
- really the same as computers...!?) He came to UTD to take some
- computer courses. He was spotted as "good" - probably by Kedem,
- but I can't swear to it - and convinced to become a full time
- graduate student.
-
- Graphics, of course, is dazzling and wonderful. Henry was (is)
- full of energy and enthusiasm. It was natural that he attracted
- lots of the grad students. Kedem was a perfect complement,
- providing not only the formal rigor and proofs, but also the
- impetus to "write this part up" before going on to "the next thing
- and the next thing and ..." Kedem and Fuchs together (and most of
- the grad students) also found a new thrust in the CS theory
- community, called computational geometry, particularly
- interesting. Henry liked to talk about the Schumacker priority
- driven visible surface algorithm when the class got to that topic.
- He seemed to think there was something more to be done in that
- vein. Naylor being a grad student in search of a topic, looked
- into it.
-
- The result was two SIGGRAPH papers and Naylor's PhD dissertation,
- and the launch of BSP-trees into the world. The two papers are
-
- Fuchs, Kedem and Naylor, "Predeterming Visibility Priority in 3-D
- Scenes" SIGGRAPH '79, pp 175-181. (subtitled "preliminary report")
-
-
- and
-
- Fuchs, Kedem and Naylor, "On Visible Surface Generation by A
- Priori Tree Structures" SIGGRAPH '80, pp124-133.
-
- The first paper isn't really BSP-trees, but rather the preliminary
- work which led to BSP-trees as the solution. The second paper is
- the "classic" starting point referenced in texts, etc.
-
- Both reference Schumacker, Brand, Gilliland and Sharp, "Study for
- Applying Computer-Generated Images to Visual Simulation"
- AFHRL-TR-69-14, US AF Human Resources Lab, 1969
-
- and the description of this algorithm more easily found in
-
- Sutherland, Sproull and Schumacker, "A Characterization of Ten
- Hidden Surface Algorithms", ACM Computing Surveys, v 6, no 1, pp
- 1-55.
-
- Naylor finished in 1981 (?) and went to Georgia Tech, and later to
- Bell Labs. He has continued to work on related and similar ideas
- with a variety of students and collaborators. Others have also
- taken the ideas in new directions.
- --
- _Last Update: 11/27/95 16:26:21_
-
- _
- Where can you find sample code and related online resources?_
-
- _BSP tree FAQ companion code_
- The companion source code to this document is available via FTP
- at:
-
- + file://ftp.qualia.com/pub/bspfaq/
-
- or, you can also request that the source be mailed to you by sending
- e-mail to bspfaq@qualia.com with a subject line of "SEND BSP TREE
- SOURCE". This will return to you a UU encoded copy of the sample
- C++ source code.
-
- _Other BSP tree resources_
- Pat Fleckenstein and Rob Reay have put together a FAQ on 3D
- graphics, which includes a blurb on BSP Trees, and an ftp site
- with some sample code. They seem to have an unusual affinity for
- ftp sites, and therefore won't link the BSP tree FAQ from their
- document:
-
- + http://www.csh.rit.edu/~pat/misc/3dFaq.html
- + file://ftp.csh.rit.edu/pub/3dfaq/
-
-
- Dr. Dobbs Journal has an article in their July '95 issue about BSP
- trees, By Nathan Dwyer. It describes the construction of BSP trees
- for visible surface processing, how to split polygons with planes,
- and how to dump the tree to a file. There is C++ source code to
- accompany the article.
-
- + http://www.ddj.com/ddj/issues/j9507a.htm
- + http://www.ddj.com/ddj/issues/j9507b.htm
-
-
- Michael Abrash's columns in the '95 DDJ Sourcebooks are an
- excellent introduction to the concept of BSP trees, especially in
- two dimensions. The source code for these is available as part of
- a package.
-
- + ftp://ftp.mv.com/pub/ddj/1995/1995.cpp/asc.zip
-
-
- Ekkehard Beier has made available a generic 3D graphics kernel
- intended to assist development of graphics application interfaces.
- One of the classes in the library is a BSP tree, and full source
- is provided. The focus seems to be on ray tracing, with the code
- being based on Jim Arvo's Linear Time Voxel Walking article in the
- ray tracing news.
-
- +
- ftp://metallica.prakinf.tu-ilmenau.de/pub/PROJECTS/GENERIC/gen
- eric1.1.tar.gz
-
-
- Eddie Edwards wrote a commonly referenced text which describes 2D
- BSP trees in some detail for use in games like DOOM. It includes a
- bit of sample code, too.
-
- +
- file://x2ftp.oulu.fi/pub/msdos/programming/theory/bsp_tree.zip
-
-
- Mel Slater has made available his C source code for computing
- shadow volumes based on BSP trees:
-
- + http://www.dcs.qmw.ac.uk/~mel/BSP.html
-
-
- _Graphics Gems_
- The Graphics Gems archive at
- file://ftp.princeton.edu/pub/Graphics/GraphicsGems/ is an
- invaluable resource for all things graphical. In particular, there
- are some BSP tree references worth looking over.
-
- Peter Shirley and Kelvin Sung have C sample code for ray tracing
- with BSP trees in Graphics Gems III
-
- Norman Chin has provided a wonderful resource for BSP trees in
- Graphics Gems V. He provides C sample code for a wide variety of
- uses.
-
- _More sources for sample BSP tree code_
- +
- file://ftp.idsoftware.com/tonsmore/utils/level_edit/node_build
- ers/
- + file://ftp.cs.brown.edu/pub/sphigs.tar.Z
-
-
- _General resources for computer graphics programming_
- Algorithm, Incorporated, an Atlanta-based Scientific and
- Engineering Research and Development Company specializing in
- Computer Graphics Programming and Business Internet
- Communications, has lots of good pointers and useful offerings.
-
- If you are interested in game programming, check out the
- rec.games.programmer.faq:
- http://www.ee.ucl.ac.uk/~phart/FAQ/rgp_FAQ.html.
- --
- _Last Update: 11/27/95 16:26:21_
-
- _
- References_
-
- A partial listing of textual info on BSP trees.
-
- 1. _Abrash, M._, BSP Trees, _Dr. Dobbs Sourcebook_, _20_(14), 49-52,
- may/jun 1995.
-
- 2. _Dadoun, N._, _Kirkpatrick, D._, and _Walsh, J._, The Geometry of
- Beam Tracing, _Proceedings of the ACM Symposium on Computational
- Geometry_, 55--61, jun 1985.
-
- 3. _Chin, N._, and _Feiner, S._, Near Real-Time Shadow Generation
- Using BSP Trees, _Computer Graphics (SIGGRAPH '89 Proceedings)_,
- _23_(3), 99--106, jul 1989.
-
- 4. _Chin, N._, and _Feiner, S._, Fast object-precision shadow
- generation for area light sources using BSP trees, _Computer
- Graphics (1992 Symposium on Interactive 3D Graphics)_, _25_(2),
- 21--30, mar 1992.
-
- 5. _Chrysanthou, Y._, and _Slater, M._, Computing dynamic changes to
- BSP trees, _Computer Graphics Forum (EUROGRAPHICS '92
- Proceedings)_, _11_(3), 321--332, sep 1992.
-
- 6. _Naylor, B._, _Amanatides, J._, and _Thibault, W._, Merging BSP
- Trees Yields Polyhedral Set Operations, _Computer Graphics
- (SIGGRAPH '90 Proceedings)_, _24_(4), 115--124, aug 1990.
-
- 7. _Chin, N._, and _Feiner, S._, Fast object-precision shadow
- generation for areal light sources using BSP trees, _Computer
- Graphics (1992 Symposium on Interactive 3D Graphics)_, _25_(2),
- 21--30, mar 1992.
-
- 8. _Naylor, B._, Interactive solid geometry via partitioning trees,
- _Proceedings of Graphics Interface '92_, 11--18, may 1992.
-
- 9. _Naylor, B._, Partitioning tree image representation and
- generation from 3D geometric models, _Proceedings of Graphics
- Interface '92_, 201--212, may 1992.
-
- 10. _Naylor, B._, {SCULPT} An Interactive Solid Modeling Tool,
- _Proceedings of Graphics Interface '90_, 138--148, may 1990.
-
- 11. _Gordon, D._, and _Chen, S._, Front-to-back display of BSP trees,
- _IEEE Computer Graphics and Applications_, _11_(5), 79--85, sep
- 1991.
-
- 12. _Ihm, I._, and _Naylor, B._, Piecewise linear approximations of
- digitized space curves with applications, _Scientific
- Visualization of Physical Phenomena (Proceedings of CG
- International '91)_, 545--569, 1991.
-
- 13. _Vanecek, G._, Brep-index: a multidimensional space partitioning
- tree, _Internat. J. Comput. Geom. Appl._, _1_(3), 243--261, 1991.
-
- 14. _Arvo, J._, Linear Time Voxel Walking for Octrees, _Ray Tracing
- News_, feb 1988.
-
- 15. _Jansen, F._, Data Structures for Ray Tracing, _Data Structures
- for Raster Graphics_, 57--73, 1986.
-
- 16. _MacDonald, J._, and _Booth, K._, Heuristics for Ray Tracing Using
- Space Subdivision, _Proceedings of Graphics Interface '89_,
- 152--63, jun 1989.
-
- 17. _Naylor, B._, and _Thibault, W._, Application of BSP Trees to Ray
- Tracing and CSG Evaluation, _Tech. Rep. GIT-ICS 86/03_, feb 1986.
-
- 18. _Sung, K._, and _Shirley, P._, Ray Tracing with the BSP Tree,
- _Graphics Gems III_, 271--274, 1992.
-
- 19. _Fuchs, H._, _Kedem, Z._, and _Naylor, B._, On Visible Surface
- Generation by A Priori Tree Structures, _Conf. Proc. of SIGGRAPH
- '80_, _14_(3), 124--133, jul 1980.
-
- 20. _Paterson, M._, and _Yao, F._, Efficient Binary Space Partitions
- for Hidden-Surface Removal and Solid Modeling, _Discrete and
- Computational Geometry_, _5_(5), 485--503, 1990.
-
-
- --
- _Last Update: 11/27/95 16:26:21_
-
-
- _________________________________________________________________
-
- BSP Tree FAQ (bspfaq@qualia.com)
-